using Core.SimpleTemp.Common;
using Core.SimpleTemp.Common.BaseLibrary;
using Core.SimpleTemp.Common.PagingQuery;
using Core.SimpleTemp.Entitys;
using Core.SimpleTemp.Repositories;
using Core.SimpleTemp.Repositories.Internal;
using Core.Toolkit.Common;
using Core.Toolkit.Core;
using Core.Toolkit.Core.Api;
using Core.Toolkit.Core.Application;
using Core.Toolkit.Core.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace Core.SimpleTemp.Application
{
    [AutoDi()]
    public class CBS_UserService : BaseAppService<CBS_UserDto, CBS_User, CBS_UserRepository>
    {
        readonly TempDirDiHelp _TempDirHelp;
        readonly ExcelHelp _excelHelp;
        readonly UserIdentity _userIdentity;
        CoreDBContext _dbContext;
        public CBS_UserService(CBS_UserRepository repository, ExcelHelp excelHelp, CoreDBContext dbContext, TempDirDiHelp tempDirHelp, IHttpContextAccessor accessor) : base(repository)
        {
            _excelHelp = excelHelp;
            _TempDirHelp = tempDirHelp;
            _dbContext = dbContext;
            if (accessor.HttpContext != null)
            {
                _userIdentity = accessor.HttpContext.User.GetUserIdentity();
            }
        }



        private LoadPageOffsetModelAuto<CBS_User, CBS_UserDto>
            GetLoadPageOffsetMode(PagingModel<CBS_UserDto>
                pagingQueryModel)
        {
            var loadPageOffsetModel = this.GetLoadPageOffsetModelAuto(pagingQueryModel);
            this.GetLoadPageOffsetModel(pagingQueryModel);
            //查询条件
            var whereEntity = pagingQueryModel.Model.ToEntity<CBS_User>();
            var where = this.CreateQRList()
                 .Add("PersonnelName", "in")
                 //.Add("sex", "=")
                 //.Add("birther", "=")
                 //.Add("IDNumber", "=")
                 //.Add("phone", "=")
                 //.Add("health", "=")
                 .Add("ConstructionCategory", "=")
                 .Add("CBSListId", "=")
                 .Add("IsBack", "=")
                //.Add("MainaAchievement", "=")
                //.Add("IsHead", "=")
                //.Add("IsQualified", "=")
                //.Add("TrainingDate", "=")
                //.Add("status", "=")
                //.Add("CreateFactory", "=")
                //.Add("CreateDept", "=")
                //.Add("UpdateDept", "=")
                ;

            //工厂处理
            if (_userIdentity.Headoffice)
                where.Add(nameof(CBS_User.CreateFactory), "="); //总部从查询条件取工厂id
            else
                where.Add(nameof(CBS_User.CreateFactory), "=", _userIdentity.Factory);
            //基础查询，联表查询在此操作
            var baseQuery = _repository.QueryBase().AsNoTracking().Include(c => c.CBS_List); 
            loadPageOffsetModel.QueryWhere = where;
            loadPageOffsetModel.Selector = model => new CBS_User()
            {
                Id = model.Id,
                PersonnelName = model.PersonnelName,
                sex = model.sex,
                birther = model.birther,
                IDNumber = model.IDNumber,
                phone = model.phone,
                //health = model.health,
                ConstructionCategory = model.ConstructionCategory,
                MainaAchievement = model.MainaAchievement,
                //IsHead = model.IsHead,
                //IsQualified = model.IsQualified,
                //TrainingDate = model.TrainingDate,
                IsBack = model.IsBack,
                CreateFactory = model.CreateFactory,
                CreateDept = model.CreateDept,
                UpdateDept = model.UpdateDept,
                TypeOfWork = model.TypeOfWork,
                CBSListId = model.CBSListId,
                CBS_List = model.CBS_List,
            };
            //按工厂过滤
            loadPageOffsetModel.BasqQuery = baseQuery.OrderByDescending(x => x.CreateTime);
            return loadPageOffsetModel;
        }


        public async Task<IPageModel<CBS_UserDto>> GetList(PagingModel<CBS_UserDto>
            pagingQueryModel)
        {
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            return await base.LoadPageOffsetAsync(loadPageOffsetModel);
        }

        public async Task<CBS_User> GetAsync(Guid id)
        {
            var basqQuery = _repository.QueryBase().AsNoTracking()
                .Include(c => c.CBS_UserAttachments)
                .Include(c => c.CBS_List);
            return await base.GetAsync(id, basqQuery);
        }

        public async Task<CBS_UserDto> UpdateAsync(CBS_UserDto dto, bool autoSave = true, List<string> noUpdateProperties = null)
        {
            var removeList = _repository._dbContext.CBS_UserAttachment.Where(c => c.CBSUserId == dto.Id);
            _repository._dbContext.RemoveRange(removeList);
            return await base.UpdateAsync(dto);
        }


        public async Task<string>
            Export(PagingModel<CBS_UserDto>
                pagingQueryModel)
        {
            var loadPageOffsetModel = GetLoadPageOffsetMode(pagingQueryModel);
            var DataList = await this.ExportDataAsync(loadPageOffsetModel);
            var excelData = DataList.Select(model => new
            {
                model.PersonnelName,
                PersonnelName_title = "人员姓名",
                model.sexText,
                sexText_title = "性别",
                model.CBS_List?.ContractorName,
                ContractorName_title = "承包商名称",
                model.birther,
                birther_title = "出生日期",
                model.IDNumber,
                IDNumber_title = "身份证号",
                model.phone,
                phone_title = "电话",
                model.ConstructionCategoryName,
                ConstructionCategoryName_title = "施工类别",
                model.TypeOfWork,
                TypeOfWork_title = "工种",
                model.MainaAchievement,
                MainaAchievement_title = "主要业绩",
                //model.IsHead,
                //IsHead_title = "是否为负责人",
                //model.IsQualified,
                //IsQualified_title = "入场培训是否合格",
                //model.TrainingDate,
                //TrainingDate_title = "培训日期",
                //model.IsBack,
                //IsBack_title = "是否黑名单",
                //model.CreateFactory,
                //CreateFactory_title = "隶属工厂",
                //model.CreateDept,
                //CreateDept_title = "",
                //model.UpdateDept,
                //UpdateDept_title = "",
            }).ToList();




            return _excelHelp.Create(excelData);
        }


        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="file"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        //public async Task<List<string>> ImportAsync(IFormFile file, string data)
        public async Task<List<string>> ImportAsync(IFormFile file)
        {
            var extension = System.IO.Path.GetExtension(file.FileName);
            var filePath = _TempDirHelp.GetFilePath(extension);
            await Filehelp.WriteFileAsync(file.OpenReadStream(), filePath);

            var dataList = new List<CBS_User>();
            var errMsgList = new List<string>();
            IWorkbook workbook = new XSSFWorkbook(filePath);
            try
            {
                var sheet = workbook.GetSheetAt(0);
                int rowCount = sheet.LastRowNum;
                //验证是否有工厂
                if (_userIdentity == null)
                {
                    errMsgList.Add($"该用户没有工厂!");
                }
                //验证模板是否正确
                var first = sheet.GetRow(0);
                if (first.GetCell(0)?.ToString() != "姓名" ||
                    first.GetCell(1)?.ToString() != "性别" ||
                    first.GetCell(2)?.ToString() != "承包商名称" ||
                    first.GetCell(3)?.ToString() != "身份证号" ||
                    first.GetCell(4)?.ToString() != "电话" ||
                    first.GetCell(5)?.ToString() != "施工类别" ||
                    first.GetCell(6)?.ToString() != "工种" ||
                    first.GetCell(7)?.ToString() != "主要业绩"
                    )
                {
                    errMsgList.Add($"请确认模板是否正确!");
                }
                for (int i = 1; i <= rowCount; i++)
                {
                    var row = sheet.GetRow(i);
                    var entity = new CBS_User();
                    if (string.IsNullOrWhiteSpace(row.GetCell(0)?.ToString()))
                        errMsgList.Add($"第{i}行，【姓名】列 不能为空！");
                    else
                        entity.PersonnelName = row.GetCell(0)?.ToString();

                    if (string.IsNullOrWhiteSpace(row.GetCell(1)?.ToString()))
                        errMsgList.Add($"第{i}行，【性别】列 不能为空！");
                    else
                    {
                        string sexName = row.GetCell(1)?.ToString();
                        if (_dbContext.Set<SysDataDic>().Where(x => x.Value == sexName && x.Category=="001").Count() > 0)
                        {
                            entity.sex = _dbContext.Set<SysDataDic>().Where(x => x.Value == sexName && x.Category == "001").FirstOrDefault().Key;
                        }
                        else
                        {
                            errMsgList.Add($"第{i}行，【性别】列 在字典表不存在！");
                        }
                    }
                        
                    if (string.IsNullOrWhiteSpace(row.GetCell(2)?.ToString()))
                        errMsgList.Add($"第{i}行，【承包商名称】列 不能为空！");
                    else
                    {
                        string ContractorName = row.GetCell(2)?.ToString();
                        if (_dbContext.Set<CBS_List>().Where(x => x.ContractorName == ContractorName).Count() > 0)
                        {
                            entity.CBSListId = _dbContext.Set<CBS_List>().Where(x => x.ContractorName == ContractorName).FirstOrDefault().Id;
                        }
                        else
                        {
                            errMsgList.Add($"第{i}行，【承包商名称】列 在承包商表不存在！");
                        }
                    }


                    if (string.IsNullOrWhiteSpace(row.GetCell(3)?.ToString()))
                        errMsgList.Add($"第{i}行，【身份证号】列 不能为空！");
                    else
                        entity.IDNumber = row.GetCell(3)?.ToString();

                    if (string.IsNullOrWhiteSpace(row.GetCell(4)?.ToString()))
                        errMsgList.Add($"第{i}行，【电话】列 不能为空！");
                    else
                        entity.phone = row.GetCell(4)?.ToString();


                    if (string.IsNullOrWhiteSpace(row.GetCell(5)?.ToString()))
                        errMsgList.Add($"第{i}行，【施工类别】列 不能为空！");
                    else
                    {
                        string ConstructionCategoryName = row.GetCell(5)?.ToString();
                        if (_dbContext.Set<SysDataDic>().Where(x => x.Value == ConstructionCategoryName && x.Category == "cbssglb").Count() > 0)
                        {
                            entity.ConstructionCategory = _dbContext.Set<SysDataDic>().Where(x => x.Value == ConstructionCategoryName && x.Category == "cbssglb").FirstOrDefault().Key;
                        }
                        else
                        {
                            errMsgList.Add($"第{i}行，【施工类别】列 在字典表不存在！");
                        }
                    }

                    if (string.IsNullOrWhiteSpace(row.GetCell(6)?.ToString()))
                        errMsgList.Add($"第{i}行，【电话】列 不能为空！");
                    else
                        entity.TypeOfWork = row.GetCell(6)?.ToString();

                    entity.MainaAchievement = row.GetCell(7)?.ToString();


                    entity.CreateFactory = _userIdentity.Factory;
                    dataList.Add(entity);
                }
            }
            catch (Exception ex)
            {
                errMsgList.Add($"导入异常:" + ex.Message);
            }
            finally
            {
                workbook.Close();
            }
            if (errMsgList.Any())
                return errMsgList;
            await _repository.Set.AddRangeAsync(dataList);
            await _repository.SaveAsync();
            System.IO.File.Delete(filePath);
            return errMsgList;
        }

    }

}
